#include <stdint.h>
#include <stdio.h>
#include <i264e_common.h>
#ifdef DMALLOC
#include <imp/dmalloc.h>
#endif
double i264e_psnr(double sqe, double size)
{
	double mse = sqe / (C_PIXEL_MAX*C_PIXEL_MAX * size);
	if(mse <= 0.0000000001) /* Max 100dB */
		return 100;
	return -10.0 * log10( mse );
}
int i264e_ftype_to_stype(int type)
{
	int stype = 0;
	switch(type) {
		case I264E_TYPE_IDR:
		case I264E_TYPE_I:
			stype = I264E_SLICE_TYPE_I;break;
		case I264E_TYPE_P:
			stype = I264E_SLICE_TYPE_P;break;
		case I264E_TYPE_B:
			stype = I264E_SLICE_TYPE_B;break;
		default :
			stype = I264E_SLICE_TYPE_B;break;
	}
	return stype;
}
int64_t i264e_pixel_ssd_wxh_tile(uint8_t *encoded_buf, uint8_t *source_buf, int i_mb_width, int i_mb_height, char plane, int expand)
{
	int64_t i_ssd = 0;
	int encoded_stride = expand > 0 ? i_mb_width + 2 : i_mb_width;
	int single_mb_height = (plane == 'y' ? 16 : 8);
	int i = 0, j = 0, x = 0, y = 0;
	uint8_t *pix1_base = NULL, *pix2_base = NULL;
	for (j = 0; j < i_mb_height; j++) {
		for (i = 0; i < i_mb_width; i++) {
			pix1_base = encoded_buf + ((j * encoded_stride) + i) * 16 * single_mb_height;
			pix2_base = source_buf + ((j * i_mb_width) + i) * 16 * single_mb_height;
			for (y = 0; y < single_mb_height; y++) {
				for (x = 0; x < 16; x++) {
					int d = 0;
					switch (plane) {
						case 'y':
							d = pix1_base[y * 16 + x] - pix2_base[y * 16 + x];
							break;
						case 'u':
							if (x < 8) {
								d = pix1_base[y * 16 + x] - pix2_base[y * 16 + x];
							}
							break;
						case 'v':
							if (x >= 8) {
								d = pix1_base[y * 16 + x] - pix2_base[y * 16 + x];
							}
							break;
						default:
							break;
					}
					i_ssd += d * d;
				}
			}
		}
	}
	return i_ssd;
}
int64_t i264e_pixel_ssd_wxh_nv12(uint8_t *encoded_buf, uint8_t *source_buf, int i_mb_width, int i_mb_height, char plane, int expand)
{
	int64_t i_ssd = 0;
	int encoded_stride = expand > 0 ? i_mb_width + 2 : i_mb_width;
	int single_mb_height = (plane == 'y' ? 16 : 8);
	int i = 0, j = 0, x = 0, y = 0;
	uint8_t *pix1_base = NULL, *pix2_base = NULL;
	for (j = 0; j < i_mb_height; j++) {
		for (i = 0; i < i_mb_width; i++) {
			pix1_base = encoded_buf + ((j * encoded_stride) + i) * 16*single_mb_height;
			pix2_base = source_buf + ((j * i_mb_width)*single_mb_height + i) * 16 ;
			for(y=0;y<single_mb_height;y++)
				for(x=0;x<16;x++){
					int d=0;
					switch (plane)
					{
						case 'y':
							d=pix1_base[x+y*16]-pix2_base[x+y*i_mb_width*16];
							break;
						case 'u':
							if(x%2==0)
								d=pix1_base[x/2+y*16]-pix2_base[x+y*i_mb_width*16];
							break;
						case 'v':
							if(x%2==1)
								d=pix1_base[x/2+y*16+8]-pix2_base[x+y*i_mb_width*16];
							break;
						default:
							break;
					}
					i_ssd+=d*d;
				}
		}
	}
	return i_ssd;
}

